﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Jage.Controls;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;
using Radar;

namespace Jage.Editor
{
    public partial class MapRenderControl : GraphicsDeviceControl
    {

        public MapRenderControl()
        {
            this.MouseMove += new MouseEventHandler(MapRenderControl_MouseMove);
            this.MouseMove += new MouseEventHandler(mapRenderControl1_MouseMove);
            this.MouseDown += new MouseEventHandler(mapRenderControl1_MouseDown);
            this.MouseUp += new MouseEventHandler(mapRenderControl1_MouseUp);
            this.MouseLeave += new EventHandler(mapRenderControl1_MouseLeave);
        }

        private Point _lastSelectedTerrainCell;
        private Point _selectedTerrainCell;
        private SpriteBatch _spriteBatchTerrain;
        private Theme _theme;

        public void SetTheme(Theme theme)
        {
            _theme = theme;
            _theme.LoadResources(new ContentManager(Services, Constants.ContentFolder));
        }

        void MapRenderControl_MouseMove(object sender, MouseEventArgs e)
        {
            if (Map != null)
            {
                _lastSelectedTerrainCell = _selectedTerrainCell;
                _selectedTerrainCell = GetTerrainCellAtScreenPos(new Point(e.X, e.Y));
                if (_lastSelectedTerrainCell != _selectedTerrainCell && TerrainSelectionChanged != null)
                {
                    TerrainSelectionChanged(this, new EventArgs());
                }
                Refresh();
            }
        }

        private Point GetTerrainCellAtScreenPos(Point pos)
        {
            return new Point((Offset.X + pos.X) / 90, (Offset.Y + pos.Y) / 60);
        }

        #region Map dragging

        bool mouseRightDown = false;
        Point mouseStartDrag;
        Point startOffset;

        private void mapRenderControl1_MouseDown(object sender, MouseEventArgs e)
        {
            if (Map != null)
            {
                if (e.Button == System.Windows.Forms.MouseButtons.Right)
                {
                    mouseRightDown = true;
                    mouseStartDrag = new Point(e.X, e.Y);
                    startOffset = Offset;
                }
            }
        }

        private void mapRenderControl1_MouseLeave(object sender, EventArgs e)
        {
            if (Map != null)
            {
                mouseRightDown = false;
            }
        }

        private void mapRenderControl1_MouseUp(object sender, MouseEventArgs e)
        {
            if (Map != null)
            {
                if (e.Button == System.Windows.Forms.MouseButtons.Right)
                {
                    mouseRightDown = false;
                }
            }
        }

        private void mapRenderControl1_MouseMove(object sender, MouseEventArgs e)
        {
            if (Map != null)
            {
                if (e.Button == System.Windows.Forms.MouseButtons.Right)
                {
                    if (mouseRightDown)
                    {
                        Offset = new Point(startOffset.X - (e.X - mouseStartDrag.X), startOffset.Y - (e.Y - mouseStartDrag.Y));
                        TerrainDragged(this, new EventArgs());
                    }
                }
            }
        }

        #endregion

        protected override void Initialize()
        {
            _spriteBatchTerrain = new SpriteBatch(this.GraphicsDevice);
        }

        protected override void Draw()
        {
            GraphicsDevice.Clear(Color.WhiteSmoke);

            if (Keyboard.GetState().IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Right))
            {
                Offset = new Point(Location.X + 1, Location.Y);
            }
            if (Map != null)
            {
                DrawTerrain();
            }
        }

        private void DrawTerrain()
        {
            int width = this.Width / 90 + 2;
            int height = this.Height / 60 + 2;
            int offsetX = Offset.X / 90;
            int offsetY = Offset.Y / 60;

            _spriteBatchTerrain.Begin();

            MapDefinition map = this.Map;

            for (int x = offsetX; x < offsetX + width && x < map.Width; x++)
            {
                for (int y = offsetY; y < offsetY + height && y < map.Height; y++)
                {
                    Color shade = Color.White;
                    Rectangle spriteRectangle = new Rectangle(x * 90 - Offset.X, y * 60 - Offset.Y,90, 60);
                    if (DrawItemMode == Editor.DrawItemMode.Terrain && new Point(x, y) == _selectedTerrainCell) shade = Color.Yellow;
                    if (map.Terrain[x, y] >= 100)
                    {
                        _spriteBatchTerrain.Draw(_theme.Terrain.GroundVariations[map.Terrain[x, y] - 100].Texture, spriteRectangle, shade);
                    }
                    else
                    {
                        _spriteBatchTerrain.Draw(_theme.Terrain.Ground[map.Terrain[x, y]].Texture, spriteRectangle, shade);
                    }
                }
            }

            _spriteBatchTerrain.End();
        }

        private Point _offset;
        public Point Offset 
        {
            get { return _offset; }
            set 
            {
                if (Map != null)
                {
                    _offset = new Point(value.X < Map.Width * 90 - Width ? value.X : Map.Width * 90 - Width, value.Y < Map.Height * 60 - Height ? value.Y : Map.Height * 60 - Height);
                    _offset = new Point(_offset.X < 0 ? 0 : _offset.X, _offset.Y < 0 ? 0 : _offset.Y);
                    this.Refresh();
                }
            }
        }

        public Point SelectedTerrainCell
        {
            get
            {
                return _selectedTerrainCell;
            }
        }

        private MapDefinition _map;
        public MapDefinition Map 
        {
            get { return _map; }
            set 
            {
                if (value != null)
                {
                    _map = value;
                    SetTheme(Theme.LoadFromFile(Constants.DataFolder + "\\" + value.ThemeFilename));
                    this.Refresh();
                }
            }
        }

        public DrawItemMode DrawItemMode { get; set; }

        public event EventHandler TerrainSelectionChanged;

        public event EventHandler TerrainDragged;

    }
}

